﻿using CodeGenerator.BaseUI;
using CodeGenerator.Common;
using CodeGenerator.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CodeGenerator.UI
{
    public partial class FrmDataBaseInfo : BaseForm
    {
        public FrmDataBaseInfo()
        {
            InitializeComponent();

            var aa = Config.GetServerList();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FrmSetup frm = new FrmSetup();
            //frm.UpdateState("程序开始启动");
            //frm.Show();


            string text = frm.Text;
            ((FrmMain)(this.ParentForm)).ShowContent(text, frm);
        }

        private void FrmDataBaseInfo_Load(object sender, EventArgs e)
        {
            var list = Config.GetServerList();
            foreach (var server in list)
            {
                TreeNode RootNode = new TreeNode();
                RootNode.Name = server.ConnectString;
                RootNode.Text = string.IsNullOrEmpty(server.Alias) ? server.ServerName + "（" + server.DatabaseType + "）" : server.Alias;
                RootNode.ImageIndex = 0;
                RootNode.SelectedImageIndex = 0;
                RootNode.Tag = new TreeNodeEx() { Type = TreeNodeType.Server, Tag = server };
                treeView1.Nodes.Add(RootNode);
            }
        }


        public delegate void UpdateTableInfoHandler(ServerInfo server,string dbName, string tableName);
        public event UpdateTableInfoHandler UpdateTableInfoEvent;

        /// <summary>
        /// 更新表名称
        /// </summary>
        public event EventHandler UpdateTableName;

        #region 工具栏
        /// <summary>
        /// 添加服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsb_add_Click(object sender, EventArgs e)
        {
            //FrmConfigSqlServer form = new FrmConfigSqlServer();

            //FrmConfigMySql form = new FrmConfigMySql();
            //form.ShowDialog();

            //ServerInfo server = form.server;
            //if (server != null)
            //{
            //    TreeNode RootNode = new TreeNode();
            //    RootNode.Name = server.ConnectString;
            //    RootNode.Text = string.IsNullOrEmpty(server.Alias) ? server.ServerName + "（" + server.DatabaseType + "）" : server.Alias;
            //    RootNode.ImageIndex = 0;
            //    RootNode.SelectedImageIndex = 0;
            //    RootNode.Tag = new TreeNodeEx() { Type = TreeNodeType.Server, Tag = server };
            //    treeView1.Nodes.Add(RootNode);

            //    // 直接连接服务器
            //    treeView1.SelectedNode = RootNode;
            //    ConnectServer();
            //}
        }

        /// <summary>
        /// 连接服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsb_link_Click(object sender, EventArgs e)
        {
            ConnectServer();
        }

        /// <summary>
        /// 注销服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsb_close_Click(object sender, EventArgs e)
        {
            RemoveServer();
        }
        #endregion

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            ConnectServer();
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode selNode = e.Node;
            // 根节点（取服务器配置信息）
            TreeNode root = Common.Utils.GetRoot(selNode);

            TreeNodeEx rootTag = (TreeNodeEx)root.Tag;
            ServerInfo server = (ServerInfo)rootTag.Tag;

            TreeNodeEx nodeTag = (TreeNodeEx)selNode.Tag;

            string dbName = "";
            string tableName = "";

            switch (nodeTag.Type)
            {
                case TreeNodeType.DataBase:
                    dbName = selNode.Text;
                    break;
                case TreeNodeType.TableNode:
                    dbName = selNode.Parent.Text;
                    break;
                case TreeNodeType.ViewNode:
                    dbName = selNode.Parent.Text;
                    break;
                case TreeNodeType.Table:
                    dbName = selNode.Parent.Parent.Text;
                    tableName = selNode.Text;

                    //FrmTableInfo form = new FrmTableInfo();
                    //form.frm = this;
                    //form.server = server;
                    //form.dbName = dbName;
                    //form.tableName = selNode.Text;

                    //((FrmMain)(this.ParentForm)).ShowContent(form.Text, form);

                    //if (UpdateTableInfoEvent != null)
                    //{
                    //    UpdateTableInfoEvent(server, dbName, selNode.Text);
                    //}

                    break;
                case TreeNodeType.View:
                    dbName = selNode.Parent.Parent.Text;
                    break;
                case TreeNodeType.Field:

                    break;
            }

            Constant.CurrentServerInfo = server; // 保存选择服务器的配置信息
            Constant.DatabaseName = dbName;
            Constant.TableName = tableName;
        }



        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                //确定右键的位置  
                Point clickPoint = new Point(e.X, e.Y);
                //在确定后的位置上面定义一个节点  
                TreeNode selNode = treeView1.GetNodeAt(clickPoint);
                if (selNode != null)
                {
                    TreeNodeEx nodeTag = (TreeNodeEx)selNode.Tag;
                    switch (nodeTag.Type)
                    {
                        case TreeNodeType.Server: 
                            treeView1.ContextMenuStrip = contextMenuStrip1;
                            break;
                        case TreeNodeType.DataBase: 
                            treeView1.ContextMenuStrip = contextMenuStrip2;
                            break;
                        case TreeNodeType.Table: 
                            treeView1.ContextMenuStrip = contextMenuStrip3;
                            break;
                        default:
                            treeView1.ContextMenuStrip = null;
                            break;
                    }

                    treeView1.SelectedNode = selNode;
                }
            }
        }

        #region 服务器节点右键 菜单事件
        private void 连接服务器ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConnectServer();
        }

        private void 断开服务器ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CloseServer();
        }

        private void 注销服务器ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemoveServer();
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 连接服务器
        /// </summary>
        private void ConnectServer(bool isRefresh = false)
        {
            // 当前节点
            TreeNode selNode = treeView1.SelectedNode;
            if(selNode==null)
            {
                return;
            }
            // 根节点（取服务器配置信息）
            TreeNode root = Common.Utils.GetRoot(selNode);
            TreeNodeEx rootTag = (TreeNodeEx)root.Tag;
            ServerInfo server = (ServerInfo)rootTag.Tag;

            if (selNode.Nodes.Count > 0 && !isRefresh) return;

            IDatabase database = DBFactory.Database(server.DBType);
            string msg;
            if (!database.TestConnnect(server, out msg))
            {
                MessageBox.Show(msg, "连接失败", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            TreeNodeEx nodeTag = (TreeNodeEx)selNode.Tag;
            switch (nodeTag.Type)
            {
                case TreeNodeType.Server: //服务器加载数据库
                    #region 服务器节点
                    var dbList = database.GetDatabaseList(server);

                    foreach (var dbName in dbList)
                    {
                        TreeNode dbNode = new TreeNode();
                        dbNode.Name = dbName;
                        dbNode.Text = dbName;
                        dbNode.ImageIndex = 1;
                        dbNode.SelectedImageIndex = 1;
                        dbNode.Tag = new TreeNodeEx() { Type = TreeNodeType.DataBase };

                        selNode.Nodes.Add(dbNode);
                    }
                    #endregion
                    break;
                case TreeNodeType.DataBase: //数据库加载表/视图节点
                    #region 添加表节点
                    //添加表根节点
                    TreeNode tableRootNode = new TreeNode();
                    tableRootNode.Name = "Table";
                    tableRootNode.Text = "Table";
                    tableRootNode.Tag = new TreeNodeEx() { Type = TreeNodeType.TableNode };
                    tableRootNode.ImageIndex = 2;
                    tableRootNode.SelectedImageIndex = 2;
                    selNode.Nodes.Add(tableRootNode);

                    var tables = database.GetTableList(server, selNode.Text);
                    foreach (var table in tables)
                    {
                        TreeNode tbNode = new TreeNode();
                        tbNode.Name = table.Name;
                        tbNode.Text = table.Name;
                        tbNode.ImageIndex = 3;
                        tbNode.SelectedImageIndex = 3;
                        tbNode.Tag = new TreeNodeEx() { Type = TreeNodeType.Table };
                        tableRootNode.Nodes.Add(tbNode);
                    }
                    #endregion
                    //#region 添加视图节点
                    ////添加视图根节点
                    //TreeNode viewNode = new TreeNode();
                    //viewNode.Name = "View";
                    //viewNode.Text = "View";
                    //viewNode.Tag = new TreeNodeEx() { Type = TreeNodeType.ViewNode };
                    //viewNode.ImageIndex = 2;
                    //viewNode.SelectedImageIndex = 2;
                    //selNode.Nodes.Add(viewNode);
                    //#endregion
                    break;
                case TreeNodeType.TableNode: //表节点加载表

                    break;
                case TreeNodeType.ViewNode: //视图节点加载视图

                    break;
            }
            selNode.Expand();
        }

        // 注销服务器
        private void RemoveServer()
        {
            TreeNode selNode = treeView1.SelectedNode;
            if (selNode == null) return;

            TreeNodeEx nodeTag = (TreeNodeEx)selNode.Tag;

            if (nodeTag.Type == TreeNodeType.Server)
            {
                ServerInfo server = nodeTag.Tag as ServerInfo;
                if (Config.RemovetServer(server))
                {
                    treeView1.Nodes.Remove(selNode);
                }
            }
        }

        // 断开服务器
        private void CloseServer()
        {
            TreeNode selNode = treeView1.SelectedNode;
            if (selNode == null) return;

            TreeNodeEx nodeTag = (TreeNodeEx)selNode.Tag;

            if (nodeTag.Type == TreeNodeType.Server)
            {
                selNode.Nodes.Clear();
            }
        }
        #endregion

        private void FrmDataBaseInfo_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        private void 表信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string dbName = "";
            string tableName = "";


            TreeNode selNode = treeView1.SelectedNode;
            // 根节点（取服务器配置信息）
            TreeNode root = Common.Utils.GetRoot(selNode);

            TreeNodeEx rootTag = (TreeNodeEx)root.Tag;
            ServerInfo server = (ServerInfo)rootTag.Tag;

            dbName = selNode.Parent.Parent.Text;
            tableName = selNode.Text;

            FrmTableInfo form = new FrmTableInfo();
            form.frm = this;
            form.server = server;
            form.dbName = dbName;
            form.tableName = selNode.Text;

            ((FrmMain)(this.ParentForm)).ShowContent(form.Text, form);

            if (UpdateTableInfoEvent != null)
            {
                UpdateTableInfoEvent(server, dbName, selNode.Text);
            }
        }

        private void chmToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process process = new Process();

            ServerInfo server = Constant.CurrentServerInfo;
            server.DatabaseName = Constant.DatabaseName;

            try
            {
                ProcessStartInfo processStartInfo = new ProcessStartInfo();
                processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                processStartInfo.FileName = Utils.GetAppPath()+"\\GeneratorDic.exe";
                processStartInfo.Arguments = Base64.EncodeBase64(server.ToJson());
                processStartInfo.UseShellExecute = false;
                process.StartInfo = processStartInfo;
                process.Start();
                process.WaitForExit();
                if (process.ExitCode == 0)
                {
                   
                }
            }
            catch
            {
               
            }
            finally
            {
                process.Close();
                
            }
        }

        private void 生成数据库文档ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ServerInfo server = Constant.CurrentServerInfo;

            if (server != null && !string.IsNullOrEmpty(Constant.DatabaseName))
            {
                FrmDict frm = new FrmDict();
                frm.ShowDialog();
            }
            else
            {
                Common.MessageUtil.ShowWarning("请先选择一个数据库1！！！");
            }
        }

        private void 实体类属性生成ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmCreateEntityMulti frm = new FrmCreateEntityMulti();
            frm.ShowDialog();
        }

        private void buildH代码生成ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmCreateBuildH form = new FrmCreateBuildH();
            ((FrmMain)(this.ParentForm)).ShowContent(form.Text, form);
        }

        private void mybatis代码生成ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmCreateMybatisSingle form = new FrmCreateMybatisSingle();
            form.Text = Constant.TableName + "--Mybatis代码生成";
            ((FrmMain)(this.ParentForm)).ShowContent(form.Text, form);
        }

        #region 实体类代码生成
        private void c简单属性代码ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string templetePath = "\\Template\\Entity\\SimpleEntity.cshtml";

            EntityCodeCreate model = GetEntityModel(CodeType.NET);

            string content = RazorHelper.RunCompile(templetePath, model);

            FrmShowCode form = new FrmShowCode(FileType.cs, content);
            form.Text = "实体类代码生成";
            ((FrmMain)(this.ParentForm)).ShowContent(form.Text, form, true);
        }

       
        private void c复杂属性代码ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string templetePath = "\\Template\\Entity\\ComplexEntity.cshtml";

            EntityCodeCreate model = GetEntityModel(CodeType.NET);

            string content = RazorHelper.RunCompile(templetePath, model);

            FrmShowCode form = new FrmShowCode(FileType.cs, content);
            form.Text = "实体类代码生成";
            ((FrmMain)(this.ParentForm)).ShowContent(form.Text, form, true);
        }

        private void java实体类ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string templetePath = "\\Template\\Entity\\JavaEntity.cshtml";

            EntityCodeCreate model = GetEntityModel(CodeType.Java);

            string content = RazorHelper.RunCompile(templetePath, model);

            FrmShowCode form = new FrmShowCode(FileType.cs, content);
            form.Text = "实体类代码生成";
            ((FrmMain)(this.ParentForm)).ShowContent(form.Text, form,true);
        }

        /// <summary>
        /// 获取生成实体代码对象
        /// </summary>
        /// <param name="codeType"></param>
        /// <returns></returns>
        private static EntityCodeCreate GetEntityModel(CodeType codeType)
        {
            EntityCodeCreate model = new EntityCodeCreate();
            TableInfo tableInfo = new TableInfo();

            ServerInfo server = Constant.CurrentServerInfo;
            IDatabase database = DBFactory.Database(server.DBType);

            string tableName = Constant.TableName;
            tableInfo.Name = tableName;
            tableInfo.Comments = database.GetTableComments(server, Constant.DatabaseName, tableName);
            tableInfo.ColumnList = database.GetColumnInfoList(server, server.DatabaseName, tableName);
            model.TableInfo = tableInfo;

            model.Name = tableName;

            MainSetting info = Config.GetSetupInfo();

            string[] prefixs = info.Prefix.Split(',');
            foreach (var prefix in prefixs)
            {
                if (!string.IsNullOrEmpty(prefix) && model.Name.Contains(prefix))
                {
                    model.Name = model.TableInfo.Name.Replace(prefix, "");
                    break;
                }
            }

            if (codeType == CodeType.NET)
            {
                model.NameSpace = info.NameSpace;
            }
            else if (codeType == CodeType.Java)
            {
                model.NameSpace = info.EntityPackage;
            }

            return model;
        }

        #endregion


        private void BuildH代码批量生成ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmCreateBuildHMulti frm = new FrmCreateBuildHMulti();
            frm.ShowDialog();
        }

        private void mybatis代码批量生成ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmCreateMybatisMulti frm = new FrmCreateMybatisMulti();
            frm.ShowDialog();
        }

        private void sqlServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmConfigSqlServer form = new FrmConfigSqlServer();
            form.ShowDialog();

            ServerInfo server = form.server;
            if (server != null)
            {
                TreeNode RootNode = new TreeNode();
                RootNode.Name = server.ConnectString;
                RootNode.Text = string.IsNullOrEmpty(server.Alias) ? server.ServerName + "（" + server.DatabaseType + "）" : server.Alias;
                RootNode.ImageIndex = 0;
                RootNode.SelectedImageIndex = 0;
                RootNode.Tag = new TreeNodeEx() { Type = TreeNodeType.Server, Tag = server };
                treeView1.Nodes.Add(RootNode);

                // 直接连接服务器
                treeView1.SelectedNode = RootNode;
                ConnectServer();
            }
        }

        private void mySqlToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmConfigMySql form = new FrmConfigMySql();
            form.ShowDialog();

            ServerInfo server = form.server;
            if (server != null)
            {
                TreeNode RootNode = new TreeNode();
                RootNode.Name = server.ConnectString;
                RootNode.Text = string.IsNullOrEmpty(server.Alias) ? server.ServerName + "（" + server.DatabaseType + "）" : server.Alias;
                RootNode.ImageIndex = 0;
                RootNode.SelectedImageIndex = 0;
                RootNode.Tag = new TreeNodeEx() { Type = TreeNodeType.Server, Tag = server };
                treeView1.Nodes.Add(RootNode);

                // 直接连接服务器
                treeView1.SelectedNode = RootNode;
                ConnectServer();
            }
        }

        private void sqliteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmConfigSqlite form = new FrmConfigSqlite();
            form.ShowDialog();

            ServerInfo server = form.server;
            if (server != null)
            {
                TreeNode RootNode = new TreeNode();
                RootNode.Name = server.ConnectString;
                RootNode.Text = string.IsNullOrEmpty(server.Alias) ? server.ServerName + "（" + server.DatabaseType + "）" : server.Alias;
                RootNode.ImageIndex = 0;
                RootNode.SelectedImageIndex = 0;
                RootNode.Tag = new TreeNodeEx() { Type = TreeNodeType.Server, Tag = server };
                treeView1.Nodes.Add(RootNode);

                // 直接连接服务器
                treeView1.SelectedNode = RootNode;
                ConnectServer();
            }
        }

        private void postgreSQLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmConfigPostgreSQL form = new FrmConfigPostgreSQL();
            form.ShowDialog();

            ServerInfo server = form.server;
            if (server != null)
            {
                TreeNode RootNode = new TreeNode();
                RootNode.Name = server.ConnectString;
                RootNode.Text = string.IsNullOrEmpty(server.Alias) ? server.ServerName + "（" + server.DatabaseType + "）" : server.Alias;
                RootNode.ImageIndex = 0;
                RootNode.SelectedImageIndex = 0;
                RootNode.Tag = new TreeNodeEx() { Type = TreeNodeType.Server, Tag = server };
                treeView1.Nodes.Add(RootNode);

                // 直接连接服务器
                treeView1.SelectedNode = RootNode;
                ConnectServer();
            }
        }
    }
}
